package com.atgouwu.scmall.seckill.controller;

import com.atgouwu.scmall.common.utils.R;
import com.atgouwu.scmall.seckill.entity.OrderEntity;
import com.atgouwu.scmall.seckill.entity.OrderItemEntity;
import com.atgouwu.scmall.seckill.service.RabbitMqService;
import org.springframework.amqp.core.AmqpAdmin;
import org.springframework.amqp.core.Binding;
import org.springframework.amqp.core.DirectExchange;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.connection.CorrelationData;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.UUID;

/**
 * RabbitMQ消息队列: 点对点:只能被一个消费者消费,接收后清除, 发布订阅(主题):被所有订阅者消费
 *                 生产者发送消息->交换机->队列->消费者监听(消费消息)
 */
@RestController
@RequestMapping("seckill/rabbitMq")
public class RabbitMqController {
    @Autowired
    private RabbitMqService rabbitMqService;

    /**
     * RabbitMQ发送消息: 通过rabbitTemplate, http://localhost:9004/middleware/rabbitMq/rabbitMq?id=1
     *                  1.pom.xml依赖:
     *                  2.appliaction.yml配置: rabbitMq连接地址
     *                  3.创建config/RabbitMqConfig配置类:
     *                    创建config/RabbitTemplateConfig配置类: 消息确认机制
     *                  4.ServiceImpl实现类: 发送消息,注解监听(接收消息):@RabbitListener(),@RabbitHandler
     */
    @GetMapping("rabbitMq")
    public R rabbitMq(@RequestParam("id") Long id) {
        String res = rabbitMqService.rabbitMq(id); //调Service接口
        return R.ok().put("data", res);
    }


    @Autowired
    private AmqpAdmin amqpAdmin;
    /**
     * RabbitMQ发送消息(创建和发送分开): 先通过amqpAdmin创建队列,创建交换机,绑定(可与发送分开), 再调下面发送, http://localhost:9004/middleware/rabbitMq/amqpAdmin?id=1
     */
    @GetMapping("/amqpAdmin")
    public R amqpAdmin(@RequestParam("id") String id) {
        amqpAdmin.declareQueue(new Queue("direct-queue", true, false, false)); //创建队列:名称,持久化,不排他,不自动删除,参数
        amqpAdmin.declareExchange(new DirectExchange("direct-exchange", true, false)); //创建交换机:名称,持久化,不自动删除,参数
        amqpAdmin.declareBinding(new Binding("direct-queue", Binding.DestinationType.QUEUE, "direct-exchange", "route-key", null)); //创建绑定:队列,绑定类型,交换机,路由键,参数
        return R.ok().put("data", id);
    }

    @Autowired
    private RabbitTemplate rabbitTemplate;
    /**
     * RabbitMQ发送消息(床架和发送一起): 先通过amqpAdmin创建队列,创建交换机,绑定 + rabbitTemplate(发送消息), http://localhost:9004/middleware/rabbitMq/amqpAdmins?id=1
     */
    @GetMapping("/amqpAdmins")
    public R amqpAdmins(@RequestParam("id") String id) {
        amqpAdmin.declareQueue(new Queue("direct-queue", true, false, false)); //创建队列:名称,持久化,不排他,不自动删除,参数
        amqpAdmin.declareExchange(new DirectExchange("direct-exchange", true, false)); //创建交换机:名称,持久化,不自动删除,参数
        amqpAdmin.declareBinding(new Binding("direct-queue", Binding.DestinationType.QUEUE, "direct-exchange", "route-key", null)); //创建绑定:队列,绑定类型,交换机,路由键,参数
        for (int i = 0; i < 5; i++) {
            OrderEntity orderEntity = new OrderEntity();
            orderEntity.setReceiverName("我爱你");
            rabbitTemplate.convertAndSend("direct-exchange", "route-key", orderEntity, new CorrelationData(UUID.randomUUID().toString())); //发送消息:交换机,路由键,任意类型消息(对象需序列化,或json配置类),消息唯一id
            OrderItemEntity orderItemEntity = new OrderItemEntity();
            orderItemEntity.setSkuName("你爱我吗");
            rabbitTemplate.convertAndSend("direct-exchange", "route-keys", orderItemEntity, new CorrelationData(UUID.randomUUID().toString())); //发送消息:交换机,路由键,任意类型消息(对象需序列化,或json配置类),消息唯一id
        }
        return R.ok().put("data", id);
    }

}
